home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_casm / snpd9611.zip / FILECAT.C < prev    next >
C/C++ Source or Header  |  1996-11-24  |  5KB  |  235 lines

  1. /* +++Date last modified: 17-Nov-1996 */
  2.  
  3. /*
  4. ** FILECAT.C - Adds one file onto another vertically, as with a column
  5. ** block in QEdit.
  6. **
  7. ** Must be compiled in Compact or Large memory models to use larger
  8. ** files.
  9. **
  10. ** Public Domain by Chad Wallace, 1996
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <alloc.h>
  15.  
  16. #ifndef FALSE
  17. #define FALSE 0
  18. #define TRUE 1
  19. #endif
  20.  
  21. /*
  22. ** filecat() error codes
  23. */
  24.  
  25. enum {
  26.       FC_SUCCESS = 0,         /* Success */
  27.       FC_RDEST,               /* Error reading dest file */
  28.       FC_WDEST,               /* Error writing dest file */
  29.       FC_SRC,                 /* Error with src file */
  30.       FC_MEM,                 /* Out of memory */
  31.       FC_LINES,               /* Too many lines (increase max_lines) */
  32.       FC_LINE                 /* Line too long (increase line_max) */
  33. };
  34.  
  35. /*
  36. ** These are global to save overhead when calling cleanup function
  37. */
  38.  
  39. static char ** str_arr;
  40. static char * temp_str;
  41.  
  42. /*
  43. ** Frees all allocated memory and closes specified file
  44. */
  45.  
  46. static void cleanup(int tot_lines, FILE * fp)
  47. {
  48.       if (str_arr)
  49.       {
  50.             for ( ; tot_lines >= 0; tot_lines--)
  51.                   free(str_arr[tot_lines]);
  52.             free(str_arr);
  53.       }
  54.       if (temp_str)
  55.             free(temp_str);
  56.       if (fp)
  57.             fclose(fp);
  58. }
  59.  
  60. int filecat(char * dest_file, char * src_file, int line_max, int max_lines)
  61. {
  62.       int i, tot_lines;
  63.       unsigned int lines_len;
  64.       FILE * fp;
  65.  
  66.       if ((temp_str = malloc(line_max + 1)) == NULL)
  67.             return FC_MEM;
  68.  
  69.       /* Allocate memory for pointers to line strings */
  70.  
  71.       if ((str_arr = calloc(max_lines + 1, sizeof(char *))) == NULL)
  72.       {
  73.             free(temp_str);
  74.             return FC_MEM;
  75.       }
  76.  
  77.       /* Open destination file */
  78.  
  79.       if ((fp = fopen(dest_file, "rt")) == NULL)
  80.       {
  81.             free(temp_str);
  82.             free(str_arr);
  83.             return FC_RDEST;
  84.       }
  85.  
  86.       /* Read destination file into string array line-by-line */
  87.  
  88.       for (i = 0;
  89.            (fgets(temp_str, line_max + 1, fp) != NULL) && (i <= max_lines);
  90.            i++)
  91.       {
  92.             /* Strip trailing newline from line read */
  93.  
  94.             if (temp_str[strlen(temp_str) - 1] == '\n')
  95.                   temp_str[strlen(temp_str) - 1] = '\0';
  96.  
  97.             /* Allocate memory */
  98.  
  99.             if ((str_arr[i] = malloc(line_max + 1)) == NULL)
  100.             {
  101.                   /* Clean up and return memory error */
  102.  
  103.                   cleanup(i, fp);
  104.  
  105.                   return FC_MEM;
  106.             }
  107.  
  108.             /* Copy the string to its new home */
  109.  
  110.             strcpy(str_arr[i], temp_str);
  111.       }
  112.  
  113.       fclose(fp);
  114.  
  115.       if (i > max_lines)
  116.       {
  117.             /* Clean up and return too many lines error */
  118.  
  119.             cleanup(i, NULL);
  120.  
  121.             return FC_LINES;
  122.       }
  123.  
  124.       /* Get length of longest line */
  125.  
  126.       lines_len = max_line(str_arr);
  127.  
  128.       /* Open source file */
  129.  
  130.       if ((fp = fopen(src_file, "rt")) == NULL)
  131.       {
  132.             /* Clean up and return source file error */
  133.  
  134.             cleanup(i, NULL);
  135.  
  136.             return FC_SRC;
  137.       }
  138.  
  139.       tot_lines = i;
  140.  
  141.       /*
  142.       ** Get each line from src file and append to corresponding line from
  143.       ** dest file
  144.       */
  145.  
  146.       for (i = 0;
  147.            (fgets(temp_str, line_max + 1, fp) != NULL) && (i < max_lines);
  148.            i++)
  149.       {
  150.             int j;
  151.  
  152.             /* Has this line been allocated yet? */
  153.  
  154.             if (str_arr[i] == NULL)
  155.             {
  156.                   /* Allocate memory */
  157.  
  158.                   if ((str_arr[i] = malloc(line_max + 1)) == NULL)
  159.                   {
  160.                         /* Clean up and return memory error */
  161.  
  162.                         cleanup(tot_lines, fp);
  163.  
  164.                         return FC_MEM;
  165.                   }
  166.  
  167.                   /* Initialize string */
  168.  
  169.                   str_arr[i][0] = '\0';
  170.  
  171.                   tot_lines++;
  172.             }
  173.  
  174.             /* Pad with spaces to make this line as long as longest */
  175.  
  176.             for (j = strlen(str_arr[i]); j < lines_len; j++)
  177.                   str_arr[i][j] = ' ';
  178.             str_arr[i][j] = '\0';
  179.  
  180.             /* Check size of resulting line when strcat'd */
  181.  
  182.             if (lines_len + strlen(temp_str) > line_max)
  183.             {
  184.                   cleanup(tot_lines, fp);
  185.  
  186.                   return FC_LINE;
  187.             }
  188.  
  189.             strcat(str_arr[i], temp_str);
  190.       }
  191.  
  192.       fclose(fp);
  193.  
  194.       if (i > max_lines)
  195.       {
  196.             /* Clean up and return too many lines error */
  197.  
  198.             cleanup(i, NULL);
  199.  
  200.             return FC_LINES;
  201.       }
  202.  
  203.       /* Open dest file again, to write this time */
  204.  
  205.       if ((fp = fopen(dest_file, "wt")) == NULL)
  206.       {
  207.             /* Clean up and return source file error */
  208.  
  209.             cleanup(i, NULL);
  210.  
  211.             return FC_WDEST;
  212.       }
  213.  
  214.       for (i = 0; i < tot_lines; i++)
  215.       {
  216.             if ((fputs(str_arr[i], fp) == EOF) /*|| (fputc('\n', fp) == EOF)*/)
  217.             {
  218.                   cleanup(i, fp);
  219.  
  220.                   return FC_WDEST;
  221.             }
  222.       }
  223.  
  224.       cleanup(i, fp);
  225.  
  226.       return FC_SUCCESS;
  227. }
  228.  
  229. int main(int argc, char ** argv)
  230. {
  231.       printf("Filecat returned %d\n", filecat(argv[1], argv[2], 2048, 4096));
  232.  
  233.       return 0;
  234. }
  235.